hvm: Always keep canonical copy of RIP/RSP/RFLAGS in
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Wed, 19 Sep 2007 13:25:44 +0000 (14:25 +0100)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Wed, 19 Sep 2007 13:25:44 +0000 (14:25 +0100)
guest_cpu_user_regs(). Reduces complexity at little or no performance
cost (except on really old Intel P4 hardware where VMREAD/VMWRITE are
silly expensive).
Signed-off-by: Keir Fraser <keir@xensource.com>
21 files changed:
xen/arch/x86/domain.c
xen/arch/x86/domctl.c
xen/arch/x86/hvm/hvm.c
xen/arch/x86/hvm/io.c
xen/arch/x86/hvm/platform.c
xen/arch/x86/hvm/svm/emulate.c
xen/arch/x86/hvm/svm/svm.c
xen/arch/x86/hvm/svm/x86_32/exits.S
xen/arch/x86/hvm/svm/x86_64/exits.S
xen/arch/x86/hvm/vmx/vmx.c
xen/arch/x86/hvm/vmx/x86_32/exits.S
xen/arch/x86/hvm/vmx/x86_64/exits.S
xen/arch/x86/mm/shadow/multi.c
xen/arch/x86/oprofile/op_model_athlon.c
xen/arch/x86/x86_32/asm-offsets.c
xen/arch/x86/x86_32/traps.c
xen/arch/x86/x86_64/asm-offsets.c
xen/arch/x86/x86_64/traps.c
xen/include/asm-x86/hvm/hvm.h
xen/include/asm-x86/hvm/svm/emulate.h
xen/include/asm-x86/hvm/vcpu.h

index a201910bdbd58ee262f517a519a71bd0262788fd..86903a8e65721b9544cbf9feeb4a26f9d2bc729f 100644 (file)
@@ -631,11 +631,11 @@ int arch_set_info_guest(
         memcpy(&v->arch.guest_context, c.nat, sizeof(*c.nat));
 #ifdef CONFIG_COMPAT
     else
-    {
         XLAT_vcpu_guest_context(&v->arch.guest_context, c.cmp);
-    }
 #endif
 
+    v->arch.guest_context.user_regs.eflags |= 2;
+
     /* Only CR0.TS is modifiable by guest or admin. */
     v->arch.guest_context.ctrlreg[0] &= X86_CR0_TS;
     v->arch.guest_context.ctrlreg[0] |= read_cr0() & ~X86_CR0_TS;
@@ -651,10 +651,6 @@ int arch_set_info_guest(
         /* Ensure real hardware interrupts are enabled. */
         v->arch.guest_context.user_regs.eflags |= EF_IE;
     }
-    else
-    {
-        hvm_load_cpu_guest_regs(v, &v->arch.guest_context.user_regs);
-    }
 
     if ( v->is_initialised )
         goto out;
index f325a79b3c4ab5dad20d8747e41fcd07b38518e0..6d96510a8108483260b7d314125453861111884e 100644 (file)
@@ -556,7 +556,6 @@ void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c)
     {
         if ( !is_pv_32on64_domain(v->domain) )
         {
-            hvm_store_cpu_guest_regs(v, &c.nat->user_regs);
             memset(c.nat->ctrlreg, 0, sizeof(c.nat->ctrlreg));
             c.nat->ctrlreg[0] = v->arch.hvm_vcpu.guest_cr[0];
             c.nat->ctrlreg[2] = v->arch.hvm_vcpu.guest_cr[2];
@@ -566,11 +565,6 @@ void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c)
 #ifdef CONFIG_COMPAT
         else
         {
-            struct cpu_user_regs user_regs;
-            unsigned i;
-
-            hvm_store_cpu_guest_regs(v, &user_regs);
-            XLAT_cpu_user_regs(&c.cmp->user_regs, &user_regs);
             memset(c.cmp->ctrlreg, 0, sizeof(c.cmp->ctrlreg));
             c.cmp->ctrlreg[0] = v->arch.hvm_vcpu.guest_cr[0];
             c.cmp->ctrlreg[2] = v->arch.hvm_vcpu.guest_cr[2];
index ad930fb99b710acac55a3ac59eded22a6bdd674b..da0bc8fcdcfec659877a1379db1107c6ef2e50b2 100644 (file)
@@ -283,8 +283,10 @@ static int hvm_save_cpu_ctxt(struct domain *d, hvm_domain_context_t *h)
         ctxt.rbp = vc->user_regs.ebp;
         ctxt.rsi = vc->user_regs.esi;
         ctxt.rdi = vc->user_regs.edi;
-        /* %rsp handled by arch-specific call above */
-#ifdef __x86_64__        
+        ctxt.rsp = vc->user_regs.esp;
+        ctxt.rip = vc->user_regs.eip;
+        ctxt.rflags = vc->user_regs.eflags;
+#ifdef __x86_64__
         ctxt.r8  = vc->user_regs.r8;
         ctxt.r9  = vc->user_regs.r9;
         ctxt.r10 = vc->user_regs.r10;
@@ -347,6 +349,8 @@ static int hvm_load_cpu_ctxt(struct domain *d, hvm_domain_context_t *h)
     vc->user_regs.esi = ctxt.rsi;
     vc->user_regs.edi = ctxt.rdi;
     vc->user_regs.esp = ctxt.rsp;
+    vc->user_regs.eip = ctxt.rip;
+    vc->user_regs.eflags = ctxt.rflags | 2;
 #ifdef __x86_64__
     vc->user_regs.r8  = ctxt.r8; 
     vc->user_regs.r9  = ctxt.r9; 
@@ -973,8 +977,6 @@ void hvm_task_switch(
         goto out;
     }
 
-    hvm_store_cpu_guest_regs(v, regs);
-
     ptss = hvm_map(prev_tr.base, sizeof(tss));
     if ( ptss == NULL )
         goto out;
@@ -1081,8 +1083,6 @@ void hvm_task_switch(
             hvm_copy_to_guest_virt(linear_addr, &errcode, 4);
     }
 
-    hvm_load_cpu_guest_regs(v, regs);
-
  out:
     hvm_unmap(optss_desc);
     hvm_unmap(nptss_desc);
@@ -1322,7 +1322,6 @@ int hvm_do_hypercall(struct cpu_user_regs *regs)
 #endif
     case 4:
     case 2:
-        hvm_store_cpu_guest_regs(current, regs);
         if ( unlikely(ring_3(regs)) )
         {
     default:
index d57f691fddaa996b759957eaacb5a26002b59680..26961642caa8cb3331f3d5bf524832b76501834d 100644 (file)
@@ -858,7 +858,6 @@ void hvm_io_assist(void)
 
     /* Copy register changes back into current guest state. */
     regs->eflags &= ~X86_EFLAGS_RF;
-    hvm_load_cpu_guest_regs(v, regs);
     memcpy(guest_cpu_user_regs(), regs, HVM_CONTEXT_STACK_BYTES);
 
  out:
index db66c9cbe43b25f80c5419f346bece675a23d18c..0b622d99ace085e2d653fa67dcc998d414baf64f 100644 (file)
@@ -1032,7 +1032,6 @@ void handle_mmio(unsigned long gpa)
 
     /* Copy current guest state into io instruction state structure. */
     memcpy(regs, guest_cpu_user_regs(), HVM_CONTEXT_STACK_BYTES);
-    hvm_store_cpu_guest_regs(v, regs);
 
     df = regs->eflags & X86_EFLAGS_DF ? 1 : 0;
 
index 9ef5a0b7bd24e5c862565c0bd5684ed2bcf64888..615c27b7cbfe59e419f9d17837d4e2717b6d5fbe 100644 (file)
@@ -59,8 +59,8 @@ extern int inst_copy_from_guest(unsigned char *buf, unsigned long guest_eip,
 #define DECODE_SIB_BASE(prefix, sib) DECODE_MODRM_RM(prefix, sib)
 
 
-static inline unsigned long DECODE_GPR_VALUE(struct vmcb_struct *vmcb, 
-        struct cpu_user_regs *regs, u8 gpr_rm)
+static inline unsigned long DECODE_GPR_VALUE(
+    struct cpu_user_regs *regs, u8 gpr_rm)
 {
     unsigned long value;
     switch (gpr_rm) 
@@ -78,7 +78,7 @@ static inline unsigned long DECODE_GPR_VALUE(struct vmcb_struct *vmcb,
         value = regs->ebx;
         break;
     case 0x4:
-        value = (unsigned long)vmcb->rsp;
+        value = regs->esp;
     case 0x5:
         value = regs->ebp;
         break;
@@ -172,7 +172,7 @@ unsigned long get_effective_addr_modrm64(struct cpu_user_regs *regs,
         }
         else
         {
-            effective_addr = DECODE_GPR_VALUE(vmcb, regs, modrm_rm);
+            effective_addr = DECODE_GPR_VALUE(regs, modrm_rm);
         }
         break;
 
@@ -202,12 +202,12 @@ unsigned long get_effective_addr_modrm64(struct cpu_user_regs *regs,
 #if __x86_64__
         /* 64-bit mode */
         if (vmcb->cs.attr.fields.l && hvm_long_mode_enabled(v))
-            return vmcb->rip + inst_len + *size + disp;
+            return regs->eip + inst_len + *size + disp;
 #endif
         return disp;
 
     default:
-        effective_addr = DECODE_GPR_VALUE(vmcb, regs, modrm_rm);
+        effective_addr = DECODE_GPR_VALUE(regs, modrm_rm);
 
     }
 
@@ -251,7 +251,7 @@ unsigned long get_effective_addr_sib(struct vmcb_struct *vmcb,
     sib_idx = DECODE_SIB_INDEX(prefix, sib);
     sib_base = DECODE_SIB_BASE(prefix, sib);
 
-    base = DECODE_GPR_VALUE(vmcb, regs, sib_base);
+    base = DECODE_GPR_VALUE(regs, sib_base);
 
     if ((unsigned long)-1 == base)
     {
@@ -293,7 +293,7 @@ unsigned long get_effective_addr_sib(struct vmcb_struct *vmcb,
     if (4 == sib_idx)
         return base;
 
-    effective_addr = DECODE_GPR_VALUE(vmcb, regs, sib_idx);
+    effective_addr = DECODE_GPR_VALUE(regs, sib_idx);
 
     effective_addr <<= sib_scale;
 
@@ -326,7 +326,8 @@ unsigned long svm_rip2pointer(struct vcpu *v)
      * no matter what kind of addressing is used.
      */
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-    unsigned long p = vmcb->cs.base + vmcb->rip;
+    unsigned long p = vmcb->cs.base + guest_cpu_user_regs()->eip;
+    ASSERT(v == current);
     if (!(vmcb->cs.attr.fields.l && hvm_long_mode_enabled(v)))
         return (u32)p; /* mask to 32 bits */
     /* NB. Should mask to 16 bits if in real mode or 16-bit protected mode. */
index b165c45dc35369d13b25a4af1222bd3675865bec..7f6b1c66b44324722f12a04c225c611a164c339f 100644 (file)
@@ -72,6 +72,14 @@ static void *root_vmcb[NR_CPUS] __read_mostly;
 /* hardware assisted paging bits */
 extern int opt_hap_enabled;
 
+static void inline __update_guest_eip(
+    struct cpu_user_regs *regs, int inst_len) 
+{
+    ASSERT(inst_len > 0);
+    regs->eip += inst_len;
+    regs->eflags &= ~X86_EFLAGS_RF;
+}
+
 static void svm_inject_exception(
     struct vcpu *v, int trap, int ev, int error_code)
 {
@@ -108,16 +116,6 @@ static int svm_lme_is_set(struct vcpu *v)
 #endif
 }
 
-static void svm_store_cpu_guest_regs(
-    struct vcpu *v, struct cpu_user_regs *regs)
-{
-    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-
-    regs->esp    = vmcb->rsp;
-    regs->eflags = vmcb->rflags;
-    regs->eip    = vmcb->rip;
-}
-
 static enum handler_return long_mode_do_msr_write(struct cpu_user_regs *regs)
 {
     u64 msr_content = (u32)regs->eax | ((u64)regs->edx << 32);
@@ -233,30 +231,11 @@ int svm_vmcb_save(struct vcpu *v, struct hvm_hw_cpu *c)
 {
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 
-    c->rip = vmcb->rip;
-
-#ifdef HVM_DEBUG_SUSPEND
-    printk("%s: eip=0x%"PRIx64".\n", 
-           __func__,
-           inst_len, c->eip);
-#endif
-
-    c->rsp = vmcb->rsp;
-    c->rflags = vmcb->rflags;
-
     c->cr0 = v->arch.hvm_vcpu.guest_cr[0];
     c->cr2 = v->arch.hvm_vcpu.guest_cr[2];
     c->cr3 = v->arch.hvm_vcpu.guest_cr[3];
     c->cr4 = v->arch.hvm_vcpu.guest_cr[4];
 
-#ifdef HVM_DEBUG_SUSPEND
-    printk("%s: cr3=0x%"PRIx64", cr0=0x%"PRIx64", cr4=0x%"PRIx64".\n",
-           __func__,
-           c->cr3,
-           c->cr0,
-           c->cr4);
-#endif
-
     c->idtr_limit = vmcb->idtr.limit;
     c->idtr_base  = vmcb->idtr.base;
 
@@ -355,10 +334,6 @@ int svm_vmcb_restore(struct vcpu *v, struct hvm_hw_cpu *c)
         v->arch.guest_table = pagetable_from_pfn(mfn);
     }
 
-    vmcb->rip    = c->rip;
-    vmcb->rsp    = c->rsp;
-    vmcb->rflags = c->rflags;
-
     v->arch.hvm_vcpu.guest_cr[0] = c->cr0 | X86_CR0_ET;
     v->arch.hvm_vcpu.guest_cr[2] = c->cr2;
     v->arch.hvm_vcpu.guest_cr[3] = c->cr3;
@@ -518,7 +493,8 @@ static int svm_interrupts_enabled(struct vcpu *v, enum hvm_intack type)
         return !vmcb->interrupt_shadow;
 
     ASSERT((type == hvm_intack_pic) || (type == hvm_intack_lapic));
-    return !irq_masked(vmcb->rflags) && !vmcb->interrupt_shadow; 
+    return (!irq_masked(guest_cpu_user_regs()->eflags) &&
+            !vmcb->interrupt_shadow);
 }
 
 static int svm_guest_x86_mode(struct vcpu *v)
@@ -527,7 +503,7 @@ static int svm_guest_x86_mode(struct vcpu *v)
 
     if ( unlikely(!(v->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE)) )
         return 0;
-    if ( unlikely(vmcb->rflags & X86_EFLAGS_VM) )
+    if ( unlikely(guest_cpu_user_regs()->eflags & X86_EFLAGS_VM) )
         return 1;
     if ( hvm_long_mode_enabled(v) && likely(vmcb->cs.attr.fields.l) )
         return 8;
@@ -785,7 +761,6 @@ static void svm_init_ap_context(
      */
     svm_reset_to_realmode(v, regs);  
     /* Adjust the vmcb's hidden register state. */
-    vmcb->rip = 0;
     vmcb->cs.sel = cs_sel;
     vmcb->cs.base = (cs_sel << 4);
 }
@@ -810,15 +785,6 @@ static void svm_init_hypercall_page(struct domain *d, void *hypercall_page)
     *(u16 *)(hypercall_page + (__HYPERVISOR_iret * 32)) = 0x0b0f; /* ud2 */
 }
 
-static void svm_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
-{
-    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-
-    vmcb->rsp      = regs->esp;   
-    vmcb->rflags   = regs->eflags | 2UL;
-    vmcb->rip      = regs->eip;
-}
-
 static void svm_ctxt_switch_from(struct vcpu *v)
 {
     int cpu = smp_processor_id();
@@ -950,8 +916,6 @@ static struct hvm_function_table svm_function_table = {
     .domain_destroy       = svm_domain_destroy,
     .vcpu_initialise      = svm_vcpu_initialise,
     .vcpu_destroy         = svm_vcpu_destroy,
-    .store_cpu_guest_regs = svm_store_cpu_guest_regs,
-    .load_cpu_guest_regs  = svm_load_cpu_guest_regs,
     .save_cpu_ctxt        = svm_save_vmcb_ctxt,
     .load_cpu_ctxt        = svm_load_vmcb_ctxt,
     .interrupts_enabled   = svm_interrupts_enabled,
@@ -1144,7 +1108,7 @@ static void svm_vmexit_do_cpuid(struct vmcb_struct *vmcb,
 
     inst_len = __get_instruction_length(v, INSTR_CPUID, NULL);
     ASSERT(inst_len > 0);
-    __update_guest_eip(vmcb, inst_len);
+    __update_guest_eip(regs, inst_len);
 }
 
 static unsigned long *get_reg_p(
@@ -1176,7 +1140,7 @@ static unsigned long *get_reg_p(
         reg_p = (unsigned long *)&regs->ebp;
         break;
     case SVM_REG_ESP:
-        reg_p = (unsigned long *)&vmcb->rsp;
+        reg_p = (unsigned long *)&regs->esp;
         break;
 #ifdef __x86_64__
     case SVM_REG_R8:
@@ -1348,7 +1312,7 @@ static int svm_get_io_address(
      * than one byte (+ maybe rep-prefix), we have some prefix so we need 
      * to figure out what it is...
      */
-    isize = vmcb->exitinfo2 - vmcb->rip;
+    isize = vmcb->exitinfo2 - regs->eip;
 
     if (info.fields.rep)
         isize --;
@@ -1501,7 +1465,6 @@ static void svm_io_instruction(struct vcpu *v)
 
     /* Copy current guest state into io instruction state structure. */
     memcpy(regs, guest_cpu_user_regs(), HVM_CONTEXT_STACK_BYTES);
-    svm_store_cpu_guest_regs(v, regs);
 
     info.bytes = vmcb->exitinfo1;
 
@@ -1524,7 +1487,7 @@ static void svm_io_instruction(struct vcpu *v)
     HVM_DBG_LOG(DBG_LEVEL_IO, 
                 "svm_io_instruction: port 0x%x eip=%x:%"PRIx64", "
                 "exit_qualification = %"PRIx64,
-                port, vmcb->cs.sel, vmcb->rip, info.bytes);
+                port, vmcb->cs.sel, (uint64_t)regs->eip, info.bytes);
 
     /* string instruction */
     if (info.fields.str)
@@ -1775,7 +1738,7 @@ static void svm_cr_access(
     if (index > 0 && (buffer[index-1] & 0xF0) == 0x40)
         prefix = buffer[index-1];
 
-    HVM_DBG_LOG(DBG_LEVEL_1, "eip = %lx", (unsigned long) vmcb->rip);
+    HVM_DBG_LOG(DBG_LEVEL_1, "eip = %lx", (unsigned long)regs->eip);
 
     switch ( match )
 
@@ -1870,7 +1833,7 @@ static void svm_cr_access(
     ASSERT(inst_len);
 
     if ( result )
-        __update_guest_eip(vmcb, inst_len);
+        __update_guest_eip(regs, inst_len);
 }
 
 static void svm_do_msr_access(
@@ -1993,14 +1956,15 @@ static void svm_do_msr_access(
         inst_len = __get_instruction_length(v, INSTR_WRMSR, NULL);
     }
 
-    __update_guest_eip(vmcb, inst_len);
+    __update_guest_eip(regs, inst_len);
 }
 
-static void svm_vmexit_do_hlt(struct vmcb_struct *vmcb)
+static void svm_vmexit_do_hlt(struct vmcb_struct *vmcb,
+                              struct cpu_user_regs *regs)
 {
     enum hvm_intack type = hvm_vcpu_has_pending_irq(current);
 
-    __update_guest_eip(vmcb, 1);
+    __update_guest_eip(regs, 1);
 
     /* Check for interrupt not handled or new interrupt. */
     if ( vmcb->eventinj.fields.v ||
@@ -2011,13 +1975,12 @@ static void svm_vmexit_do_hlt(struct vmcb_struct *vmcb)
     }
 
     HVMTRACE_1D(HLT, current, /*int pending=*/ 0);
-    hvm_hlt(vmcb->rflags);
+    hvm_hlt(regs->eflags);
 }
 
-static void svm_vmexit_do_invd(struct vcpu *v)
+static void svm_vmexit_do_invd(struct cpu_user_regs *regs)
 {
-    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-    int  inst_len;
+    int inst_len;
     
     /* Invalidate the cache - we can't really do that safely - maybe we should 
      * WBINVD, but I think it's just fine to completely ignore it - we should 
@@ -2029,8 +1992,8 @@ static void svm_vmexit_do_invd(struct vcpu *v)
      */
     gdprintk(XENLOG_WARNING, "INVD instruction intercepted - ignored\n");
     
-    inst_len = __get_instruction_length(v, INSTR_INVD, NULL);
-    __update_guest_eip(vmcb, inst_len);
+    inst_len = __get_instruction_length(current, INSTR_INVD, NULL);
+    __update_guest_eip(regs, inst_len);
 }    
         
 void svm_handle_invlpg(const short invlpga, struct cpu_user_regs *regs)
@@ -2039,7 +2002,6 @@ void svm_handle_invlpg(const short invlpga, struct cpu_user_regs *regs)
     u8 opcode[MAX_INST_LEN], prefix, length = MAX_INST_LEN;
     unsigned long g_vaddr;
     int inst_len;
-    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 
     /* 
      * Unknown how many bytes the invlpg instruction will take.  Use the
@@ -2056,7 +2018,7 @@ void svm_handle_invlpg(const short invlpga, struct cpu_user_regs *regs)
     {
         inst_len = __get_instruction_length(v, INSTR_INVLPGA, opcode);
         ASSERT(inst_len > 0);
-        __update_guest_eip(vmcb, inst_len);
+        __update_guest_eip(regs, inst_len);
 
         /* 
          * The address is implicit on this instruction. At the moment, we don't
@@ -2083,7 +2045,7 @@ void svm_handle_invlpg(const short invlpga, struct cpu_user_regs *regs)
                                              &opcode[inst_len], &length);
 
         inst_len += length;
-        __update_guest_eip (vmcb, inst_len);
+        __update_guest_eip(regs, inst_len);
     }
 
     HVMTRACE_3D(INVLPG, v, (invlpga?1:0), g_vaddr, (invlpga?regs->ecx:0));
@@ -2106,6 +2068,8 @@ static int svm_reset_to_realmode(struct vcpu *v,
 
     memset(regs, 0, sizeof(struct cpu_user_regs));
 
+    regs->eflags = 2;
+
     v->arch.hvm_vcpu.guest_cr[0] = X86_CR0_ET;
     svm_update_guest_cr(v, 0);
 
@@ -2118,7 +2082,7 @@ static int svm_reset_to_realmode(struct vcpu *v,
     vmcb->efer = EFER_SVME;
 
     /* This will jump to ROMBIOS */
-    vmcb->rip = 0xFFF0;
+    regs->eip = 0xFFF0;
 
     /* Set up the segment registers and all their hidden states. */
     vmcb->cs.sel = 0xF000;
@@ -2171,16 +2135,12 @@ static int svm_reset_to_realmode(struct vcpu *v,
     vmcb->idtr.limit = 0x3ff;
     vmcb->idtr.base = 0x00;
 
-    vmcb->rax = 0;
-    vmcb->rsp = 0;
-
     return 0;
 }
 
 asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs)
 {
     unsigned int exit_reason;
-    unsigned long eip;
     struct vcpu *v = current;
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
     eventinj_t eventinj;
@@ -2198,7 +2158,7 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs)
 
     exit_reason = vmcb->exitcode;
 
-    HVMTRACE_2D(VMEXIT, v, vmcb->rip, exit_reason);
+    HVMTRACE_2D(VMEXIT, v, regs->eip, exit_reason);
 
     if ( unlikely(exit_reason == VMEXIT_INVALID) )
     {
@@ -2207,7 +2167,6 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs)
     }
 
     perfc_incra(svmexits, exit_reason);
-    eip = vmcb->rip;
 
     /* Event delivery caused this intercept? Queue for redelivery. */
     eventinj = vmcb->exitintinfo;
@@ -2244,7 +2203,7 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs)
             goto exit_and_crash;
         /* AMD Vol2, 15.11: INT3, INTO, BOUND intercepts do not update RIP. */
         inst_len = __get_instruction_length(v, INSTR_INT3, NULL);
-        __update_guest_eip(vmcb, inst_len);
+        __update_guest_eip(regs, inst_len);
         domain_pause_for_debugger();
         break;
 
@@ -2275,7 +2234,6 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs)
 
     case VMEXIT_EXCEPTION_MC:
         HVMTRACE_0D(MCE, v);
-        svm_store_cpu_guest_regs(v, regs);
         do_machine_check(regs);
         break;
 
@@ -2285,7 +2243,7 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs)
         break;
 
     case VMEXIT_INVD:
-        svm_vmexit_do_invd(v);
+        svm_vmexit_do_invd(regs);
         break;
 
     case VMEXIT_TASK_SWITCH: {
@@ -2308,7 +2266,7 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs)
         break;
 
     case VMEXIT_HLT:
-        svm_vmexit_do_hlt(vmcb);
+        svm_vmexit_do_hlt(vmcb, regs);
         break;
 
     case VMEXIT_INVLPG:
@@ -2326,7 +2284,7 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs)
         rc = hvm_do_hypercall(regs);
         if ( rc != HVM_HCALL_preempted )
         {
-            __update_guest_eip(vmcb, inst_len);
+            __update_guest_eip(regs, inst_len);
             if ( rc == HVM_HCALL_invalidate )
                 send_invalidate_req();
         }
index ba5c064b68c634b866ac491fbe4171e088c09c6d..f9c29a6d9562d3506a82a63790c600aba94576c5 100644 (file)
@@ -58,6 +58,12 @@ svm_trace_done:
         movl VCPU_svm_vmcb(%ebx),%ecx
         movl UREGS_eax(%esp),%eax
         movl %eax,VMCB_rax(%ecx)
+        movl UREGS_eip(%esp),%eax
+        movl %eax,VMCB_rip(%ecx)
+        movl UREGS_esp(%esp),%eax
+        movl %eax,VMCB_rsp(%ecx)
+        movl UREGS_eflags(%esp),%eax
+        movl %eax,VMCB_rflags(%ecx)
 
         movl VCPU_svm_vmcb_pa(%ebx),%eax
         popl %ebx
@@ -81,6 +87,12 @@ svm_trace_done:
         movl VCPU_svm_vmcb(%ebx),%ecx
         movl VMCB_rax(%ecx),%eax
         movl %eax,UREGS_eax(%esp)
+        movl VMCB_rip(%ecx),%eax
+        movl %eax,UREGS_eip(%esp)
+        movl VMCB_rsp(%ecx),%eax
+        movl %eax,UREGS_esp(%esp)
+        movl VMCB_rflags(%ecx),%eax
+        movl %eax,UREGS_eflags(%esp)
 
         STGI
 .globl svm_stgi_label;
index e991bb4cd4f1bc83d2a2d77a8d0bae31fd713b62..99ffea4a8f80db6109474d452235f1607af50960 100644 (file)
@@ -59,6 +59,12 @@ svm_trace_done:
         movq VCPU_svm_vmcb(%rbx),%rcx
         movq UREGS_rax(%rsp),%rax
         movq %rax,VMCB_rax(%rcx)
+        movq UREGS_rip(%rsp),%rax
+        movq %rax,VMCB_rip(%rcx)
+        movq UREGS_rsp(%rsp),%rax
+        movq %rax,VMCB_rsp(%rcx)
+        movq UREGS_eflags(%rsp),%rax
+        movq %rax,VMCB_rflags(%rcx)
 
         movq VCPU_svm_vmcb_pa(%rbx),%rax
         popq %r15
@@ -100,6 +106,12 @@ svm_trace_done:
         movq VCPU_svm_vmcb(%rbx),%rcx
         movq VMCB_rax(%rcx),%rax
         movq %rax,UREGS_rax(%rsp)
+        movq VMCB_rip(%rcx),%rax
+        movq %rax,UREGS_rip(%rsp)
+        movq VMCB_rsp(%rcx),%rax
+        movq %rax,UREGS_rsp(%rsp)
+        movq VMCB_rflags(%rcx),%rax
+        movq %rax,UREGS_eflags(%rsp)
 
         STGI
 .globl svm_stgi_label;
index eabb3691608add9f4d1cbb7cfa8e2b6d59173d35..cb88ab5c6c6a4cd8b10163d05932742480fcae5c 100644 (file)
@@ -437,11 +437,9 @@ static int vmx_guest_x86_mode(struct vcpu *v)
 {
     unsigned int cs_ar_bytes;
 
-    ASSERT(v == current);
-
     if ( unlikely(!(v->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE)) )
         return 0;
-    if ( unlikely(__vmread(GUEST_RFLAGS) & X86_EFLAGS_VM) )
+    if ( unlikely(guest_cpu_user_regs()->eflags & X86_EFLAGS_VM) )
         return 1;
     cs_ar_bytes = __vmread(GUEST_CS_AR_BYTES);
     if ( hvm_long_mode_enabled(v) &&
@@ -485,10 +483,6 @@ void vmx_vmcs_save(struct vcpu *v, struct hvm_hw_cpu *c)
 
     vmx_vmcs_enter(v);
 
-    c->rip = __vmread(GUEST_RIP);
-    c->rsp = __vmread(GUEST_RSP);
-    c->rflags = __vmread(GUEST_RFLAGS);
-
     c->cr0 = v->arch.hvm_vcpu.guest_cr[0];
     c->cr2 = v->arch.hvm_vcpu.guest_cr[2];
     c->cr3 = v->arch.hvm_vcpu.guest_cr[3];
@@ -496,11 +490,6 @@ void vmx_vmcs_save(struct vcpu *v, struct hvm_hw_cpu *c)
 
     c->msr_efer = v->arch.hvm_vcpu.guest_efer;
 
-#ifdef HVM_DEBUG_SUSPEND
-    printk("%s: cr3=0x%"PRIx64", cr0=0x%"PRIx64", cr4=0x%"PRIx64".\n",
-           __func__, c->cr3, c->cr0, c->cr4);
-#endif
-
     c->idtr_limit = __vmread(GUEST_IDTR_LIMIT);
     c->idtr_base = __vmread(GUEST_IDTR_BASE);
 
@@ -594,10 +583,6 @@ int vmx_vmcs_restore(struct vcpu *v, struct hvm_hw_cpu *c)
 
     vmx_vmcs_enter(v);
 
-    __vmwrite(GUEST_RIP, c->rip);
-    __vmwrite(GUEST_RSP, c->rsp);
-    __vmwrite(GUEST_RFLAGS, c->rflags);
-
     v->arch.hvm_vcpu.guest_cr[0] = c->cr0 | X86_CR0_ET;
     v->arch.hvm_vcpu.guest_cr[2] = c->cr2;
     v->arch.hvm_vcpu.guest_cr[3] = c->cr3;
@@ -793,30 +778,6 @@ static void vmx_ctxt_switch_to(struct vcpu *v)
     vmx_restore_dr(v);
 }
 
-static void vmx_store_cpu_guest_regs(
-    struct vcpu *v, struct cpu_user_regs *regs)
-{
-    vmx_vmcs_enter(v);
-
-    regs->eflags = __vmread(GUEST_RFLAGS);
-    regs->eip = __vmread(GUEST_RIP);
-    regs->esp = __vmread(GUEST_RSP);
-
-    vmx_vmcs_exit(v);
-}
-
-static void vmx_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
-{
-    vmx_vmcs_enter(v);
-
-    /* NB. Bit 1 of RFLAGS must be set for VMENTRY to succeed. */
-    __vmwrite(GUEST_RFLAGS, regs->eflags | 2UL);
-    __vmwrite(GUEST_RIP, regs->eip);
-    __vmwrite(GUEST_RSP, regs->esp);
-
-    vmx_vmcs_exit(v);
-}
-
 static unsigned long vmx_get_segment_base(struct vcpu *v, enum x86_segment seg)
 {
     unsigned long base = 0;
@@ -1061,9 +1022,7 @@ static void vmx_init_hypercall_page(struct domain *d, void *hypercall_page)
 
 static int vmx_interrupts_enabled(struct vcpu *v, enum hvm_intack type)
 {
-    unsigned long intr_shadow, eflags;
-
-    ASSERT(v == current);
+    unsigned long intr_shadow;
 
     intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO);
 
@@ -1073,8 +1032,7 @@ static int vmx_interrupts_enabled(struct vcpu *v, enum hvm_intack type)
                                 VMX_INTR_SHADOW_NMI));
 
     ASSERT((type == hvm_intack_pic) || (type == hvm_intack_lapic));
-    eflags = __vmread(GUEST_RFLAGS);
-    return (!irq_masked(eflags) &&
+    return (!irq_masked(guest_cpu_user_regs()->eflags) &&
             !(intr_shadow & (VMX_INTR_SHADOW_STI|VMX_INTR_SHADOW_MOV_SS)));
 }
 
@@ -1193,8 +1151,6 @@ static struct hvm_function_table vmx_function_table = {
     .domain_destroy       = vmx_domain_destroy,
     .vcpu_initialise      = vmx_vcpu_initialise,
     .vcpu_destroy         = vmx_vcpu_destroy,
-    .store_cpu_guest_regs = vmx_store_cpu_guest_regs,
-    .load_cpu_guest_regs  = vmx_load_cpu_guest_regs,
     .save_cpu_ctxt        = vmx_save_vmcs_ctxt,
     .load_cpu_ctxt        = vmx_load_vmcs_ctxt,
     .interrupts_enabled   = vmx_interrupts_enabled,
@@ -1284,14 +1240,11 @@ static int __get_instruction_length(void)
 
 static void __update_guest_eip(unsigned long inst_len)
 {
+    struct cpu_user_regs *regs = guest_cpu_user_regs();
     unsigned long x;
 
-    x = __vmread(GUEST_RIP);
-    __vmwrite(GUEST_RIP, x + inst_len);
-
-    x = __vmread(GUEST_RFLAGS);
-    if ( x & X86_EFLAGS_RF )
-        __vmwrite(GUEST_RFLAGS, x & ~X86_EFLAGS_RF);
+    regs->eip += inst_len;
+    regs->eflags &= ~X86_EFLAGS_RF;
 
     x = __vmread(GUEST_INTERRUPTIBILITY_INFO);
     if ( x & (VMX_INTR_SHADOW_STI | VMX_INTR_SHADOW_MOV_SS) )
@@ -1435,16 +1388,10 @@ static void vmx_dr_access(unsigned long exit_qualification,
  */
 static void vmx_do_invlpg(unsigned long va)
 {
-    unsigned long eip;
     struct vcpu *v = current;
 
     HVMTRACE_2D(INVLPG, v, /*invlpga=*/ 0, va);
 
-    eip = __vmread(GUEST_RIP);
-
-    HVM_DBG_LOG(DBG_LEVEL_VMMU, "eip=%lx, va=%lx",
-                eip, va);
-
     /*
      * We do the safest things first, then try to update the shadow
      * copying from guest
@@ -1852,7 +1799,6 @@ static void vmx_io_instruction(unsigned long exit_qualification,
 
     /* Copy current guest state into io instruction state structure. */
     memcpy(regs, guest_cpu_user_regs(), HVM_CONTEXT_STACK_BYTES);
-    vmx_store_cpu_guest_regs(current, regs);
 
     HVM_DBG_LOG(DBG_LEVEL_IO, "vm86 %d, eip=%x:%lx, "
                 "exit_qualification = %lx",
@@ -1891,12 +1837,12 @@ static void vmx_io_instruction(unsigned long exit_qualification,
 
 static void vmx_world_save(struct vcpu *v, struct vmx_assist_context *c)
 {
-    /* NB. Skip transition instruction. */
-    c->eip = __vmread(GUEST_RIP);
-    c->eip += __get_instruction_length(); /* Safe: MOV Cn, LMSW, CLTS */
+    struct cpu_user_regs *regs = guest_cpu_user_regs();
 
-    c->esp = __vmread(GUEST_RSP);
-    c->eflags = __vmread(GUEST_RFLAGS) & ~X86_EFLAGS_RF;
+    c->eip  = regs->eip;
+    c->eip += __get_instruction_length(); /* Safe: MOV Cn, LMSW, CLTS */
+    c->esp = regs->esp;
+    c->eflags = regs->eflags & ~X86_EFLAGS_RF;
 
     c->cr0 = v->arch.hvm_vcpu.guest_cr[0];
     c->cr3 = v->arch.hvm_vcpu.guest_cr[3];
@@ -1951,6 +1897,7 @@ static void vmx_world_save(struct vcpu *v, struct vmx_assist_context *c)
 
 static int vmx_world_restore(struct vcpu *v, struct vmx_assist_context *c)
 {
+    struct cpu_user_regs *regs = guest_cpu_user_regs();
     unsigned long mfn = 0;
     p2m_type_t p2mt;
 
@@ -1969,9 +1916,9 @@ static int vmx_world_restore(struct vcpu *v, struct vmx_assist_context *c)
 
     v->arch.guest_table = pagetable_from_pfn(mfn);
 
-    __vmwrite(GUEST_RIP, c->eip);
-    __vmwrite(GUEST_RSP, c->esp);
-    __vmwrite(GUEST_RFLAGS, c->eflags);
+    regs->eip = c->eip;
+    regs->esp = c->esp;
+    regs->eflags = c->eflags | 2;
 
     v->arch.hvm_vcpu.guest_cr[0] = c->cr0;
     v->arch.hvm_vcpu.guest_cr[3] = c->cr3;
@@ -2121,7 +2068,6 @@ static int vmx_assist(struct vcpu *v, int mode)
 static int vmx_set_cr0(unsigned long value)
 {
     struct vcpu *v = current;
-    unsigned long eip;
     int rc = hvm_set_cr0(value);
 
     if ( rc == 0 )
@@ -2142,24 +2088,12 @@ static int vmx_set_cr0(unsigned long value)
     if ( !(value & X86_CR0_PE) )
     {
         if ( vmx_assist(v, VMX_ASSIST_INVOKE) )
-        {
-            eip = __vmread(GUEST_RIP);
-            HVM_DBG_LOG(DBG_LEVEL_1,
-                        "Transfering control to vmxassist %%eip 0x%lx", eip);
             return 0; /* do not update eip! */
-        }
     }
     else if ( v->arch.hvm_vmx.vmxassist_enabled )
     {
-        eip = __vmread(GUEST_RIP);
-        HVM_DBG_LOG(DBG_LEVEL_1,
-                    "Enabling CR0.PE at %%eip 0x%lx", eip);
         if ( vmx_assist(v, VMX_ASSIST_RESTORE) )
-        {
-            HVM_DBG_LOG(DBG_LEVEL_1,
-                        "Restoring to %%eip 0x%lx", eip);
             return 0; /* do not update eip! */
-        }
     }
 
     return 1;
@@ -2204,10 +2138,8 @@ static int mov_to_cr(int gp, int cr, struct cpu_user_regs *regs)
     CASE_GET_REG(EBP, ebp);
     CASE_GET_REG(ESI, esi);
     CASE_GET_REG(EDI, edi);
+    CASE_GET_REG(ESP, esp);
     CASE_EXTEND_GET_REG;
-    case REG_ESP:
-        value = __vmread(GUEST_RSP);
-        break;
     default:
         gdprintk(XENLOG_ERR, "invalid gp: %d\n", gp);
         goto exit_and_crash;
@@ -2276,11 +2208,8 @@ static void mov_from_cr(int cr, int gp, struct cpu_user_regs *regs)
     CASE_SET_REG(EBP, ebp);
     CASE_SET_REG(ESI, esi);
     CASE_SET_REG(EDI, edi);
+    CASE_SET_REG(ESP, esp);
     CASE_EXTEND_SET_REG;
-    case REG_ESP:
-        __vmwrite(GUEST_RSP, value);
-        regs->esp = value;
-        break;
     default:
         printk("invalid gp: %d\n", gp);
         domain_crash(v->domain);
@@ -2521,12 +2450,10 @@ gp_fault:
     return 0;
 }
 
-static void vmx_do_hlt(void)
+static void vmx_do_hlt(struct cpu_user_regs *regs)
 {
-    unsigned long rflags;
     HVMTRACE_0D(HLT, current);
-    rflags = __vmread(GUEST_RFLAGS);
-    hvm_hlt(rflags);
+    hvm_hlt(regs->eflags);
 }
 
 static void vmx_do_extint(struct cpu_user_regs *regs)
@@ -2601,7 +2528,6 @@ static void vmx_failed_vmentry(unsigned int exit_reason,
     case EXIT_REASON_MACHINE_CHECK:
         printk("caused by machine check.\n");
         HVMTRACE_0D(MCE, current);
-        vmx_store_cpu_guest_regs(current, regs);
         do_machine_check(regs);
         break;
     default:
@@ -2624,7 +2550,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
 
     exit_reason = __vmread(VM_EXIT_REASON);
 
-    HVMTRACE_2D(VMEXIT, v, __vmread(GUEST_RIP), exit_reason);
+    HVMTRACE_2D(VMEXIT, v, regs->eip, exit_reason);
 
     perfc_incra(vmexits, exit_reason);
 
@@ -2723,12 +2649,10 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
                  (X86_EVENTTYPE_NMI << 8) )
                 goto exit_and_crash;
             HVMTRACE_0D(NMI, v);
-            vmx_store_cpu_guest_regs(v, regs);
             do_nmi(regs); /* Real NMI, vector 2: normal processing. */
             break;
         case TRAP_machine_check:
             HVMTRACE_0D(MCE, v);
-            vmx_store_cpu_guest_regs(v, regs);
             do_machine_check(regs);
             break;
         default:
@@ -2775,7 +2699,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
     case EXIT_REASON_HLT:
         inst_len = __get_instruction_length(); /* Safe: HLT */
         __update_guest_eip(inst_len);
-        vmx_do_hlt();
+        vmx_do_hlt(regs);
         break;
     case EXIT_REASON_INVLPG:
     {
index 7f080bccd47b3a4fa29e3d197fa813d36cb91568..986900f1aaddab276f1e9aef046a2d088d8b0447 100644 (file)
 #include <asm/page.h>
 #include <public/xen.h>
 
+#define VMRESUME     .byte 0x0f,0x01,0xc3
+#define VMLAUNCH     .byte 0x0f,0x01,0xc2
+#define VMREAD(off)  .byte 0x0f,0x78,0x44,0x24,off
+#define VMWRITE(off) .byte 0x0f,0x79,0x44,0x24,off
+
+/* VMCS field encodings */
+#define GUEST_RSP    0x681c
+#define GUEST_RIP    0x681e
+#define GUEST_RFLAGS 0x6820
+
 #define GET_CURRENT(reg)         \
         movl $STACK_SIZE-4, reg; \
         orl  %esp, reg;          \
         ALIGN
 ENTRY(vmx_asm_vmexit_handler)
         HVM_SAVE_ALL_NOSEGREGS
+
+        movl $GUEST_RIP,%eax
+        VMREAD(UREGS_eip)
+        movl $GUEST_RSP,%eax
+        VMREAD(UREGS_esp)
+        movl $GUEST_RFLAGS,%eax
+        VMREAD(UREGS_eflags)
+
         movl %esp,%eax
         push %eax
         call vmx_vmexit_handler
@@ -78,13 +96,19 @@ ENTRY(vmx_asm_do_vmentry)
         movl %eax,%cr2
         call vmx_trace_vmentry
 
+        movl $GUEST_RIP,%eax
+        VMWRITE(UREGS_eip)
+        movl $GUEST_RSP,%eax
+        VMWRITE(UREGS_esp)
+        movl $GUEST_RFLAGS,%eax
+        VMWRITE(UREGS_eflags)
+
         cmpl $0,VCPU_vmx_launched(%ebx)
         je   vmx_launch
 
 /*vmx_resume:*/
         HVM_RESTORE_ALL_NOSEGREGS
-        /* VMRESUME */
-        .byte 0x0f,0x01,0xc3
+        VMRESUME
         pushf
         call vm_resume_fail
         ud2
@@ -92,8 +116,7 @@ ENTRY(vmx_asm_do_vmentry)
 vmx_launch:
         movl $1,VCPU_vmx_launched(%ebx)
         HVM_RESTORE_ALL_NOSEGREGS
-        /* VMLAUNCH */
-        .byte 0x0f,0x01,0xc2
+        VMLAUNCH
         pushf
         call vm_launch_fail
         ud2
index 5b2527d055df514cb670661c3f6da5d708878e2e..6f59c1bbb8088643484e243543d7ff3b83b8bb46 100644 (file)
 #include <asm/page.h>
 #include <public/xen.h>
 
+#define VMRESUME     .byte 0x0f,0x01,0xc3
+#define VMLAUNCH     .byte 0x0f,0x01,0xc2
+#define VMREAD(off)  .byte 0x0f,0x78,0x44,0x24,off
+#define VMWRITE(off) .byte 0x0f,0x79,0x44,0x24,off
+
+/* VMCS field encodings */
+#define GUEST_RSP    0x681c
+#define GUEST_RIP    0x681e
+#define GUEST_RFLAGS 0x6820
+
 #define GET_CURRENT(reg)         \
         movq $STACK_SIZE-8, reg; \
         orq  %rsp, reg;          \
         ALIGN
 ENTRY(vmx_asm_vmexit_handler)
         HVM_SAVE_ALL_NOSEGREGS
+
+        movl $GUEST_RIP,%eax
+        VMREAD(UREGS_rip)
+        movl $GUEST_RSP,%eax
+        VMREAD(UREGS_rsp)
+        movl $GUEST_RFLAGS,%eax
+        VMREAD(UREGS_eflags)
+
         movq %rsp,%rdi
         call vmx_vmexit_handler
         jmp vmx_asm_do_vmentry
@@ -92,13 +110,19 @@ ENTRY(vmx_asm_do_vmentry)
         movq %rax,%cr2
         call vmx_trace_vmentry
 
+        movl $GUEST_RIP,%eax
+        VMWRITE(UREGS_rip)
+        movl $GUEST_RSP,%eax
+        VMWRITE(UREGS_rsp)
+        movl $GUEST_RFLAGS,%eax
+        VMWRITE(UREGS_eflags)
+
         cmpl $0,VCPU_vmx_launched(%rbx)
         je   vmx_launch
 
 /*vmx_resume:*/
         HVM_RESTORE_ALL_NOSEGREGS
-        /* VMRESUME */
-        .byte 0x0f,0x01,0xc3
+        VMRESUME
         pushfq
         call vm_resume_fail
         ud2
@@ -106,8 +130,7 @@ ENTRY(vmx_asm_do_vmentry)
 vmx_launch:
         movl $1,VCPU_vmx_launched(%rbx)
         HVM_RESTORE_ALL_NOSEGREGS
-        /* VMLAUNCH */
-        .byte 0x0f,0x01,0xc2
+        VMLAUNCH
         pushfq
         call vm_launch_fail
         ud2
index a68c1e06e0c057d1fa7fd7634875f4a93eb9606e..df0892ec7b9271b659893b44174c344621742dbb 100644 (file)
@@ -2928,8 +2928,6 @@ static int sh_page_fault(struct vcpu *v,
             sh_remove_shadows(v, gmfn, 0 /* thorough */, 1 /* must succeed */);
             goto done;
         }
-
-        hvm_store_cpu_guest_regs(v, regs);
     }
 
     SHADOW_PRINTK("emulate: eip=%#lx esp=%#lx\n", 
@@ -2993,10 +2991,6 @@ static int sh_page_fault(struct vcpu *v,
     }
 #endif /* PAE guest */
 
-    /* Emulator has changed the user registers: write back */
-    if ( is_hvm_domain(d) )
-        hvm_load_cpu_guest_regs(v, regs);
-
     SHADOW_PRINTK("emulated\n");
     return EXCRET_fault_fixed;
 
index d3c757a57ee5a34d1710d6f705ac299ae3a6c715..2ffc192f0c8d61b2dcd738e1541e1aaf3e9b5b3f 100644 (file)
@@ -119,7 +119,6 @@ static int athlon_check_ctrs(unsigned int const cpu,
            (regs->eip == (unsigned long)svm_stgi_label)) {
                /* SVM guest was running when NMI occurred */
                ASSERT(is_hvm_vcpu(v));
-               hvm_store_cpu_guest_regs(v, guest_regs);
                eip = guest_regs->eip;
                mode = xenoprofile_get_mode(v, guest_regs);
        } else {
index fc276245c7d142e041b605fd5340b691298edfca..86e3682e0ada7a246ab5343abef335fa7df7c5db 100644 (file)
@@ -89,6 +89,9 @@ void __dummy__(void)
     BLANK();
 
     OFFSET(VMCB_rax, struct vmcb_struct, rax);
+    OFFSET(VMCB_rip, struct vmcb_struct, rip);
+    OFFSET(VMCB_rsp, struct vmcb_struct, rsp);
+    OFFSET(VMCB_rflags, struct vmcb_struct, rflags);
     BLANK();
 
     OFFSET(VCPUINFO_upcall_pending, vcpu_info_t, evtchn_upcall_pending);
index dcee52f65f3703e91db24469981441b2abdd72d3..bcbc14908c02c89368065ba180f44f7f29dc4d1b 100644 (file)
@@ -47,7 +47,6 @@ void show_registers(struct cpu_user_regs *regs)
     {
         struct segment_register sreg;
         context = "hvm";
-        hvm_store_cpu_guest_regs(v, &fault_regs);
         fault_crs[0] = v->arch.hvm_vcpu.guest_cr[0];
         fault_crs[2] = v->arch.hvm_vcpu.guest_cr[2];
         fault_crs[3] = v->arch.hvm_vcpu.guest_cr[3];
index eb3f623351f7855f2617e17cc3d79597864a70d9..120f0d0e3d71c0452328128c398fd5d4e955435f 100644 (file)
@@ -95,6 +95,9 @@ void __dummy__(void)
     BLANK();
 
     OFFSET(VMCB_rax, struct vmcb_struct, rax);
+    OFFSET(VMCB_rip, struct vmcb_struct, rip);
+    OFFSET(VMCB_rsp, struct vmcb_struct, rsp);
+    OFFSET(VMCB_rflags, struct vmcb_struct, rflags);
     BLANK();
 
     OFFSET(VCPUINFO_upcall_pending, struct vcpu_info, evtchn_upcall_pending);
index ed48005da3fe4f8d5c324db4e9974888f2b4c394..992bf8d45cb63da64831368c067acce51c8cdc8b 100644 (file)
@@ -50,7 +50,6 @@ void show_registers(struct cpu_user_regs *regs)
     {
         struct segment_register sreg;
         context = "hvm";
-        hvm_store_cpu_guest_regs(v, &fault_regs);
         fault_crs[0] = v->arch.hvm_vcpu.guest_cr[0];
         fault_crs[2] = v->arch.hvm_vcpu.guest_cr[2];
         fault_crs[3] = v->arch.hvm_vcpu.guest_cr[3];
index 475e374ee683a8e576177d8697bb5dcb290d3acb..f2cc1f99a710bf048bab3ae6774f588a3072fa18 100644 (file)
@@ -21,6 +21,7 @@
 #ifndef __ASM_X86_HVM_HVM_H__
 #define __ASM_X86_HVM_HVM_H__
 
+#include <asm/current.h>
 #include <asm/x86_emulate.h>
 #include <public/domctl.h>
 #include <public/hvm/save.h>
@@ -79,16 +80,6 @@ struct hvm_function_table {
     int  (*vcpu_initialise)(struct vcpu *v);
     void (*vcpu_destroy)(struct vcpu *v);
 
-    /*
-     * Store and load guest state:
-     * 1) load/store guest register state,
-     * 2) modify guest state (e.g., set debug flags).
-     */
-    void (*store_cpu_guest_regs)(
-        struct vcpu *v, struct cpu_user_regs *r);
-    void (*load_cpu_guest_regs)(
-        struct vcpu *v, struct cpu_user_regs *r);
-
     /* save and load hvm guest cpu context for save/restore */
     void (*save_cpu_ctxt)(struct vcpu *v, struct hvm_hw_cpu *ctxt);
     int (*load_cpu_ctxt)(struct vcpu *v, struct hvm_hw_cpu *ctxt);
@@ -166,19 +157,6 @@ void hvm_vcpu_reset(struct vcpu *vcpu);
 
 void hvm_send_assist_req(struct vcpu *v);
 
-static inline void
-hvm_store_cpu_guest_regs(
-    struct vcpu *v, struct cpu_user_regs *r)
-{
-    hvm_funcs.store_cpu_guest_regs(v, r);
-}
-
-static inline void
-hvm_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *r)
-{
-    hvm_funcs.load_cpu_guest_regs(v, r);
-}
-
 void hvm_set_guest_time(struct vcpu *v, u64 gtime);
 u64 hvm_get_guest_time(struct vcpu *v);
 
@@ -199,12 +177,14 @@ u64 hvm_get_guest_time(struct vcpu *v);
 static inline int
 hvm_interrupts_enabled(struct vcpu *v, enum hvm_intack type)
 {
+    ASSERT(v == current);
     return hvm_funcs.interrupts_enabled(v, type);
 }
 
 static inline int
 hvm_guest_x86_mode(struct vcpu *v)
 {
+    ASSERT(v == current);
     return hvm_funcs.guest_x86_mode(v);
 }
 
index 8c183b89de2fb7c9ffddd22cbb08ce687e85be55..c31194c940fa7993bec12b7178d16630a3f4b1bd 100644 (file)
@@ -131,16 +131,6 @@ static inline int skip_prefix_bytes(u8 *buf, size_t size)
     return index;
 }
 
-
-
-static void inline __update_guest_eip(
-    struct vmcb_struct *vmcb, int inst_len) 
-{
-    ASSERT(inst_len > 0);
-    vmcb->rip += inst_len;
-    vmcb->rflags &= ~X86_EFLAGS_RF;
-}
-
 #endif /* __ASM_X86_HVM_SVM_EMULATE_H__ */
 
 /*
index d790eb2037a4479ef2edae5e6d622a0f7ede2143..e2738557e4b685e1ac1b9677d118372e3ff1b449 100644 (file)
@@ -66,7 +66,7 @@ struct hvm_vcpu {
 
 #define ARCH_HVM_IO_WAIT         1   /* Waiting for I/O completion */
 
-#define HVM_CONTEXT_STACK_BYTES  (offsetof(struct cpu_user_regs, error_code))
+#define HVM_CONTEXT_STACK_BYTES  (offsetof(struct cpu_user_regs, ss))
 
 #endif /* __ASM_X86_HVM_VCPU_H__ */